﻿using System;
using System.ComponentModel;
using System.Linq;
using System.Net;
using System.Reflection;
using System.Xml;
using SPEventReceiverManager.Properties;
using Microsoft.SharePoint;
using System.IO;

namespace SPEventReceiverManager.AutoUpdater
{
    public class UpdateReaultEventArgs : EventArgs
    {
        public string DownloadUrl
        {
            get;
            set;
        }
    }

    internal class UpdaterService : IDisposable
    {
        private BackgroundWorker m_BackgroundWorker;

        public UpdaterService()
        {
            this.m_BackgroundWorker = new BackgroundWorker();
            this.m_BackgroundWorker.DoWork += (_, e) => this.CheckForUpdates();
        }

        ~UpdaterService()
        {
            this.Dispose(false);
        }

        public event EventHandler<UpdateReaultEventArgs> UpdateAvailable;

        public void CheckForUpdatesAsync()
        {
            if (!this.m_BackgroundWorker.IsBusy)
            {
                this.m_BackgroundWorker.RunWorkerAsync();
            }
        }

        public void Dispose()
        {
            this.Dispose(true);
            GC.SuppressFinalize(this);
        }

        protected virtual void OnUpdateAvaliable(string downloadId)
        {
            if (this.UpdateAvailable != null)
            {
                UpdateReaultEventArgs args = new UpdateReaultEventArgs()
                {
                    DownloadUrl = Settings.Default.DownloadBaseUrl + downloadId
                };

                this.UpdateAvailable(this, args);
            }
        }

        protected virtual void Dispose(bool disposing)
        {
            if (disposing && this.m_BackgroundWorker != null)
            {
                this.m_BackgroundWorker.Dispose();
            }
        }

        private void CheckForUpdates()
        {
            var updateUrl = Settings.Default.VersionHistoryUrl;
            var currentVersion = Assembly.GetExecutingAssembly().GetName().Version;
            Assembly spAssembly = Assembly.GetAssembly(typeof(SPSite));

            string spPlatform = spAssembly.GetName().Version.Major == 14 ? "2010" : "2007";

            string downloadId = "";

            Version version = new Version("1.0.0.0");

            XmlReader xmlReader;

            try
            {
                HttpWebRequest request = WebRequest.Create(updateUrl) as HttpWebRequest;

                // Get response  
                using (HttpWebResponse response = request.GetResponse() as HttpWebResponse)
                {
                    // Get the response stream  
                    Stream stream = response.GetResponseStream();

                    xmlReader = XmlReader.Create(stream);


                    while (xmlReader.Read())
                    {
                        if (string.Equals(xmlReader.Name, "Version", StringComparison.OrdinalIgnoreCase))
                        {
                            string v = xmlReader.GetAttribute("Number");
                            string p = xmlReader.GetAttribute("Platform");

                            Version t = new Version(v);

                            if ((p == spPlatform) && (t > version))
                            {
                                downloadId = xmlReader.GetAttribute("DownloadId");
                                version = t;
                            }
                        }
                    }
                }
            }
            catch (WebException)
            {
                return;
            }

            if (version != currentVersion)
            {
                this.OnUpdateAvaliable(downloadId);
            }
        }
    }
}
